package pl;

import javacard.framework.JCSystem;
import javacard.framework.Util;

public class PrimitiveBERTLV extends BERTLV {

	public PrimitiveBERTLV(short numValueBytes) 
	{
		theValue = new byte[numValueBytes];
	}
	
	public short init(byte[] bArray, short bOff, short bLen) 
	{
		this.valueLength = bLen;
		this.valueOffset = bOff;
		Util.arrayCopy(bArray, bOff, theValue, AppletControler.O, bLen);
		bOff += bLen;
		BERTLV.getInstance(bArray, bOff, bLen);
		return bLen;
	}
	
	public short init(PrimitiveBERTag tag, byte[] vArray, short vOff, short vLen)
	{
		if (vArray == null) throw new NullPointerException();
		
		if (true)//((short)(vArray.length - vOff) ==  vLen)
		{	
			// tag
			this.theBERTag = tag;

			// length
			
			// value 
			Util.arrayCopy(vArray, vOff, theValue, (short)0, vLen);	
			
			this.emptyTLV = false;
			this.valueLength = vLen;
			
			return (short)theValue.length;
		}
		else
		{
			throw new ArrayIndexOutOfBoundsException(); 
		}
	}
	
	public short size() 
	{
		if (valueLength < 127) return (short) (valueLength + this.theBERTag.tagSizeInBytes + 1 );
		else if (valueLength > 127 && valueLength < 256) return (short) (valueLength + this.theBERTag.tagSizeInBytes + 2 );
		else 
			return (short) (valueLength + this.theBERTag.tagSizeInBytes + 3 );
	}

	// TODO: Test
	public short toBytes(byte[] outBuf, short bOff) throws ArrayIndexOutOfBoundsException, NullPointerException 
	{
		if (outBuf == null) throw new NullPointerException();
		
		if ((short)(outBuf.length + bOff) >=  (short)(this.getLength() + 2))
		//if ((short)(outBuf.length - bOff) >=  (short)(this.getLength()))
		{	
			short offset = bOff;
			
			// tag
			this.theBERTag.toBytes(outBuf, offset);			
			if (this.theBERTag.size() == 1) offset++;
			else if (this.theBERTag.size() == 2) offset += 2;
			else throw new NullPointerException(); 
			
			// length && value
			if(this.valueLength < 128) 
			{
				outBuf[offset] = (byte)valueLength;
				offset++;	
			}
			if(this.valueLength > 127 && this.valueLength < 256) 
			{
				outBuf[offset] = (byte)0x81;
				outBuf[(short)(offset + 1)] = (byte)valueLength;
				offset += 2;
			}
			
			if(this.valueLength > 255 && this.valueLength < 32767) 
			{
				outBuf[offset] = (byte)0x82;
				outBuf[(short)(offset + 1)] = Utils.shortOnByteArray(valueLength)[1];
				outBuf[(short)(offset + 2)] = Utils.shortOnByteArray(valueLength)[0];
				offset += 3;
			}
			
			Util.arrayCopy(theValue, (short)0 , outBuf, offset, (short)valueLength);
			
			//Util.arrayCopy(new byte[]{1,2}, (short)0 , outBuf, offset, (short)2);
			//Util.arrayCopy(theValue, (short)0  , outBuf, (short) (offset + bOff), (short)theValue.length);
			
			return (short)outBuf.length;
		}
		else 
			throw new ArrayIndexOutOfBoundsException(); 
	}
}
